home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / think / AmigaGnuChess.lha / chess / src.lha / src / eval.c < prev    next >
C/C++ Source or Header  |  1992-09-01  |  35KB  |  1,436 lines

  1. /*
  2.  * eval.c - C source for GNU CHESS
  3.  *
  4.  * Copyright (c) 1988,1989,1990 John Stanback
  5.  * Copyright (c) 1992 Free Software Foundation
  6.  *
  7.  * This file is part of GNU CHESS.
  8.  *
  9.  * GNU Chess is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * GNU Chess is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with GNU Chess; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23. #include "gnuchess.h"
  24. #include "ataks.h"
  25. short int sscore[2];
  26. /* Backward pawn bonus indexed by # of attackers on the square */
  27. static const short BACKWARD[16] =
  28. {-6, -10, -15, -21, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28};
  29.  
  30. /* Bishop mobility bonus indexed by # reachable squares */
  31. static const short BMBLTY[14] =
  32. {-2, 0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16, 16, 16};
  33.  
  34. /* Rook mobility bonus indexed by # reachable squares */
  35. static const short RMBLTY[15] =
  36. {0, 2, 4, 6, 8, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14};
  37.  
  38. /* Positional values for a dying king */
  39. static const short DyingKing[64] =
  40. {0, 8, 16, 24, 24, 16, 8, 0,
  41.  8, 32, 40, 48, 48, 40, 32, 8,
  42.  16, 40, 56, 64, 64, 56, 40, 16,
  43.  24, 48, 64, 72, 72, 64, 48, 24,
  44.  24, 48, 64, 72, 72, 64, 48, 24,
  45.  16, 40, 56, 64, 64, 56, 40, 16,
  46.  8, 32, 40, 48, 48, 40, 32, 8,
  47.  0, 8, 16, 24, 24, 16, 8, 0};
  48.  
  49. /* Isoloted pawn penalty by rank */
  50. static const short ISOLANI[8] =
  51. {-12, -16, -20, -24, -24, -20, -16, -12};
  52.  
  53. /* table for King Bishop Knight endings */
  54. static const short KBNK[64] =
  55. {99, 90, 80, 70, 60, 50, 40, 40,
  56.  90, 80, 60, 50, 40, 30, 20, 40,
  57.  80, 60, 40, 30, 20, 10, 30, 50,
  58.  70, 50, 30, 10, 0, 20, 40, 60,
  59.  60, 40, 20, 0, 10, 30, 50, 70,
  60.  50, 30, 10, 20, 30, 40, 60, 80,
  61.  40, 20, 30, 40, 50, 60, 80, 90,
  62.  40, 40, 50, 60, 70, 80, 90, 99};
  63.  
  64. /* penalty for threats to king, indexed by number of such threats */
  65. static const short KTHRT[36] =
  66. {0, -8, -20, -36, -52, -68, -80, -80, -80, -80, -80, -80,
  67.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
  68.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80};
  69.  
  70. /* King positional bonus inopening stage */
  71. static const short KingOpening[64] =
  72. {0, 0, -4, -10, -10, -4, 0, 0,
  73.  -4, -4, -8, -12, -12, -8, -4, -4,
  74.  -12, -16, -20, -20, -20, -20, -16, -12,
  75.  -16, -20, -24, -24, -24, -24, -20, -16,
  76.  -16, -20, -24, -24, -24, -24, -20, -16,
  77.  -12, -16, -20, -20, -20, -20, -16, -12,
  78.  -4, -4, -8, -12, -12, -8, -4, -4,
  79.  0, 0, -4, -10, -10, -4, 0, 0};
  80.  
  81. /* King positional bonus in end stage */
  82. static const short KingEnding[64] =
  83. {0, 6, 12, 18, 18, 12, 6, 0,
  84.  6, 12, 18, 24, 24, 18, 12, 6,
  85.  12, 18, 24, 30, 30, 24, 18, 12,
  86.  18, 24, 30, 36, 36, 30, 24, 18,
  87.  18, 24, 30, 36, 36, 30, 24, 18,
  88.  12, 18, 24, 30, 30, 24, 18, 12,
  89.  6, 12, 18, 24, 24, 18, 12, 6,
  90.  0, 6, 12, 18, 18, 12, 6, 0};
  91.  
  92. /* Passed pawn positional bonus */
  93. static const short PassedPawn0[8] =
  94. {0, 60, 80, 120, 200, 360, 600, 800};
  95. static const short PassedPawn1[8] =
  96. {0, 30, 40, 60, 100, 180, 300, 800};
  97. static const short PassedPawn2[8] =
  98. {0, 15, 25, 35, 50, 90, 140, 800};
  99. static const short PassedPawn3[8] =
  100. {0, 5, 10, 15, 20, 30, 140, 800};
  101.  
  102. /* Knight positional bonus */
  103. static const short pknight[64] =
  104. {0, 4, 8, 10, 10, 8, 4, 0,
  105.  4, 8, 16, 20, 20, 16, 8, 4,
  106.  8, 16, 24, 28, 28, 24, 16, 8,
  107.  10, 20, 28, 32, 32, 28, 20, 10,
  108.  10, 20, 28, 32, 32, 28, 20, 10,
  109.  8, 16, 24, 28, 28, 24, 16, 8,
  110.  4, 8, 16, 20, 20, 16, 8, 4,
  111.  0, 4, 8, 10, 10, 8, 4, 0};
  112.  
  113. /* Bishop positional bonus */
  114. static const short pbishop[64] =
  115. {14, 14, 14, 14, 14, 14, 14, 14,
  116.  14, 22, 18, 18, 18, 18, 22, 14,
  117.  14, 18, 22, 22, 22, 22, 18, 14,
  118.  14, 18, 22, 22, 22, 22, 18, 14,
  119.  14, 18, 22, 22, 22, 22, 18, 14,
  120.  14, 18, 22, 22, 22, 22, 18, 14,
  121.  14, 22, 18, 18, 18, 18, 22, 14,
  122.  14, 14, 14, 14, 14, 14, 14, 14};
  123.  
  124. /* Pawn positional bonus */
  125. static const short PawnAdvance[64] =
  126. {0, 0, 0, 0, 0, 0, 0, 0,
  127.  4, 4, 4, 0, 0, 4, 4, 4,
  128.  6, 8, 2, 10, 10, 2, 8, 6,
  129.  6, 8, 12, 16, 16, 12, 8, 6,
  130.  8, 12, 16, 24, 24, 16, 12, 8,
  131.  12, 16, 24, 32, 32, 24, 16, 12,
  132.  12, 16, 24, 32, 32, 24, 16, 12,
  133.  0, 0, 0, 0, 0, 0, 0, 0};
  134. #if !defined NOSCORESPACE
  135. #ifdef BLACKAG0
  136. /* Space positional bonus */
  137. static const short SpaceBonusB[64] =
  138. {0, 0, 0, 0, 0, 0, 0, 0,
  139.  0, 0, 2, 2, 2, 2, 0, 0,
  140.  1, 1, 2, 4, 4, 2, 1, 1,
  141.  0, 0, 3, 4, 4, 3, 0, 0,
  142.  0, 0, 5, 5, 5, 5, 0, 0,
  143.  0, 0, 4, 4, 7, 7, 0, 0,
  144.  0, 0, 0, 0, 0, 0, 0, 0,
  145.  0, 0, 0, 0, 0, 0, 0, 0};
  146. #elif defined BLACKAG1
  147. /* Space positional bonus */
  148. static const short SpaceBonusB[64] =
  149. {1, 1, 1, 1, 1, 1, 1, 1,
  150.  1, 1, 2, 2, 2, 2, 1, 1,
  151.  1, 1, 2, 3, 3, 2, 1, 1,
  152.  1, 1, 2, 4, 4, 2, 1, 1,
  153.  1, 1, 3, 5, 5, 3, 1, 1,
  154.  1, 1, 3, 6, 6, 3, 1, 1,
  155.  1, 1, 3, 7, 7, 3, 1, 1,
  156.  1, 1, 1, 1, 1, 1, 1, 1};
  157. #elif defined BLACKAG2
  158. /* Space positional bonus */
  159. static const short SpaceBonusB[64] =
  160. {1, 1, 1, 1, 1, 1, 1, 1,
  161.  1, 1, 2, 2, 2, 2, 1, 1,
  162.  1, 1, 3, 3, 3, 3, 1, 1,
  163.  1, 1, 4, 4, 4, 4, 1, 1,
  164.  1, 1, 5, 6, 6, 5, 1, 1,
  165.  1, 1, 6, 7, 7, 6, 1, 1,
  166.  1, 1, 7, 8, 8, 7, 1, 1,
  167.  1, 1, 1, 1, 1, 1, 1, 1};
  168. #elif defined BLACKAG3
  169. /* Space positional bonus */
  170. static const short SpaceBonusB[64] =
  171. {0, 0, 0, 0, 0, 0, 0, 0,
  172.  0, 0, 2, 2, 2, 2, 0, 0,
  173.  0, 0, 3, 3, 3, 3, 0, 0,
  174.  0, 0, 4, 4, 4, 3, 0, 0,
  175.  0, 0, 6, 6, 4, 4, 0, 0,
  176.  0, 0, 7, 7, 5, 5, 0, 0,
  177.  0, 0, 8, 8, 7, 7, 0, 0,
  178.  0, 0, 0, 0, 0, 0, 0, 0};
  179. #elif defined BLACKAG4
  180. /* Space positional bonus */
  181. static const short SpaceBonusB[64] =
  182. {1, 1, 1, 1, 1, 1, 1, 1,
  183.  1, 1, 2, 4, 4, 2, 1, 1,
  184.  1, 1, 2, 4, 4, 2, 1, 1,
  185.  1, 1, 2, 4, 4, 2, 1, 1,
  186.  1, 1, 2, 4, 4, 2, 1, 1,
  187.  1, 1, 2, 4, 4, 2, 1, 1,
  188.  1, 1, 2, 4, 4, 2, 1, 1,
  189.  1, 1, 1, 1, 1, 1, 1, 1};
  190. #endif
  191.  
  192. #ifdef WHITEAG0
  193. /* Space positional bonus */
  194. static const short SpaceBonusW[64] =
  195. {0, 0, 0, 0, 0, 0, 0, 0,
  196.  0, 0, 5, 5, 5, 5, 0, 0,
  197.  0, 0, 3, 4, 4, 3, 0, 0,
  198.  0, 0, 2, 4, 4, 2, 0, 0,
  199.  0, 0, 1, 4, 4, 1, 0, 0,
  200.  0, 0, 1, 4, 4, 1, 0, 0,
  201.  0, 0, 1, 2, 2, 1, 0, 0,
  202.  0, 0, 0, 0, 0, 0, 0, 0};
  203. #elif defined WHITEAG1
  204. /* Space positional bonus */
  205. static const short SpaceBonusW[64] =
  206. {1, 1, 1, 1, 1, 1, 1, 1,
  207.  1, 1, 3, 7, 7, 3, 1, 1,
  208.  1, 1, 3, 6, 6, 3, 1, 1,
  209.  1, 1, 3, 5, 5, 3, 1, 1,
  210.  1, 1, 2, 4, 4, 2, 1, 1,
  211.  1, 1, 2, 3, 3, 2, 1, 1,
  212.  1, 1, 2, 2, 2, 2, 1, 1,
  213.  1, 1, 1, 1, 1, 1, 1, 1};
  214. #elif defined WHITEAG2
  215. /* Space positional bonus */
  216. static const short SpaceBonusW[64] =
  217. {1, 1, 1, 1, 1, 1, 1, 1,
  218.  1, 1, 7, 8, 8, 7, 1, 1,
  219.  1, 1, 6, 7, 7, 6, 1, 1,
  220.  1, 1, 5, 6, 6, 5, 1, 1,
  221.  1, 1, 4, 4, 4, 4, 1, 1,
  222.  1, 1, 3, 3, 3, 3, 1, 1,
  223.  1, 1, 2, 2, 2, 2, 1, 1,
  224.  1, 1, 1, 1, 1, 1, 1, 1};
  225. #elif defined WHITEAG3
  226. /* Space positional bonus */
  227. static const short SpaceBonusW[64] =
  228. {0, 0, 0, 0, 0, 0, 0, 0,
  229.  0, 0, 8, 8, 7, 7, 0, 0,
  230.  0, 0, 7, 7, 5, 5, 0, 0,
  231.  0, 0, 6, 6, 4, 4, 0, 0,
  232.  0, 0, 4, 4, 4, 3, 0, 0,
  233.  0, 0, 3, 3, 3, 3, 0, 0,
  234.  0, 0, 2, 2, 2, 2, 0, 0,
  235.  0, 0, 0, 0, 0, 0, 0, 0};
  236. #elif defined WHITEAG4
  237. /* Space positional bonus */
  238. static const short SpaceBonusW[64] =
  239. {1, 1, 1, 1, 1, 1, 1, 1,
  240.  1, 1, 2, 4, 4, 2, 1, 1,
  241.  1, 1, 2, 4, 4, 2, 1, 1,
  242.  1, 1, 2, 4, 4, 2, 1, 1,
  243.  1, 1, 2, 4, 4, 2, 1, 1,
  244.  1, 1, 2, 4, 4, 2, 1, 1,
  245.  1, 1, 2, 4, 4, 2, 1, 1,
  246.  1, 1, 1, 1, 1, 1, 1, 1};
  247. #endif
  248. #endif
  249.  
  250. short Mwpawn[64], Mbpawn[64], Mknight[2][64], Mbishop[2][64];
  251. static short Mking[2][64], Kfield[2][64];
  252. static short c1, c2, *atk1, *atk2, *PC1, *PC2, atak[2][64];
  253. short emtl[2];
  254. static short PawnBonus, BishopBonus, RookBonus;
  255. static short KNIGHTPOST, KNIGHTSTRONG, BISHOPSTRONG, KATAK;
  256. static short PEDRNK2B, PWEAKH, PADVNCM, PADVNCI, PAWNSHIELD, PDOUBLED,
  257.  PBLOK;
  258. static short RHOPN, RHOPNX, KHOPN, KHOPNX, KSFTY;
  259. static short ATAKD, HUNGP, HUNGX, KCASTLD, KMOVD, XRAY, PINVAL;
  260. short pscore[2];
  261. short tmtl;
  262.  
  263. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  264.  
  265. /*
  266.  * Inputs are:
  267.  * pmtl[side] - value of pawns
  268.  * mtl[side]  - value of all material
  269.  * emtl[side] - vaule of all material - value of pawns - value of king
  270.  * hung[side] - count of hung pieces
  271.  * Tscore[ply] - search tree score for ply
  272.  * ply
  273.  * Pscore[ply] - positional score for ply ply
  274.  * INCscore    - bonus score or penalty for certain positions
  275.  * slk - single lone king flag
  276.  * Sdepth - search goal depth
  277.  * xwndw - evaluation window about alpha/beta
  278.  * EWNDW - second evaluation window about alpha/beta
  279.  * ChkFlag[ply]- checking piece at level ply or 0 if no check
  280.  */
  281. inline
  282. short
  283. ScoreKPK (short int side,
  284.       short int winner,
  285.       short int loser,
  286.       short int king1,
  287.       register short int king2,
  288.       register short int sq)
  289.  
  290. /*
  291.  * Score King and Pawns versus King endings.
  292.  */
  293.  
  294. {
  295.   register short s, r;
  296.  
  297.   s = ((PieceCnt[winner] == 1) ? 50 : 120);
  298.   if (winner == white)
  299.     {
  300.       r = row (sq) - ((side == loser) ? 1 : 0);
  301.       if (row (king2) >= r && distance (sq, king2) < 8 - r)
  302.     s += 10 * row (sq);
  303.       else
  304.     s = 500 + 50 * row (sq);
  305.       if (row (sq) < 6)
  306.     sq += 16;
  307.       else if (row (sq) == 6)
  308.     sq += 8;
  309.     }
  310.   else
  311.     {
  312.       r = row (sq) + ((side == loser) ? 1 : 0);
  313.       if (row (king2) <= r && distance (sq, king2) < r + 1)
  314.     s += 10 * (7 - row (sq));
  315.       else
  316.     s = 500 + 50 * (7 - row (sq));
  317.       if (row (sq) > 1)
  318.     sq -= 16;
  319.       else if (row (sq) == 1)
  320.     sq -= 8;
  321.     }
  322.   s += 8 * (taxicab (king2, sq) - taxicab (king1, sq));
  323. #if defined(AMIGADB)&&defined(LATTICE)
  324.   {
  325.   if (abs(s) >= 10000)
  326.     flash(),fprintf(stderr, "eval1: s = %d\n", s);
  327.   return (s);
  328.   }
  329. #else
  330.   return (s);
  331. #endif
  332. }
  333.  
  334.  
  335. inline
  336. short
  337. ScoreKBNK (short int winner, short int king1, short int king2)
  338.  
  339.  
  340. /*
  341.  * Score King+Bishop+Knight versus King endings. This doesn't work all that
  342.  * well but it's better than nothing.
  343.  */
  344.  
  345. {
  346.   register short s, sq, KBNKsq = 0;
  347.  
  348.   for (sq = 0; sq < 64; sq++)
  349.     if (board[sq] == bishop)
  350.       KBNKsq = (((row (sq) % 2) == (column (sq) % 2)) ? 0 : 7);
  351.  
  352.   s = emtl[winner] - 300;
  353.   s += ((KBNKsq == 0) ? KBNK[king2] : KBNK[locn (row (king2), 7 - column (king2))]);
  354.   s -= ((taxicab (king1, king2) + distance (PieceList[winner][1], king2) + distance (PieceList[winner][2], king2)));
  355. #if defined(AMIGADB)&&defined(LATTICE)
  356.   {
  357.   if (abs(s) >= 10000)
  358.     flash(),fprintf(stderr, "eval2: s = %d\n", s);
  359.   return (s);
  360.   }
  361. #else
  362.   return (s);
  363. #endif
  364. }
  365.  
  366. inline
  367. short int
  368. ScoreLoneKing (short int side)
  369.  
  370. /*
  371.  * Static evaluation when loser has only a king and winner has no pawns or no
  372.  * pieces.
  373.  */
  374.  
  375. {
  376.   register short winner, loser, king1, king2, s, i;
  377.  
  378.   UpdateWeights ();
  379.   winner = ((mtl[white] > mtl[black]) ? white : black);
  380.   loser = winner ^ 1;
  381.   king1 = PieceList[winner][0];
  382.   king2 = PieceList[loser][0];
  383.  
  384.   s = 0;
  385.  
  386.   if (pmtl[winner] > 0)
  387.     for (i = 1; i <= PieceCnt[winner]; i++)
  388.       s += ScoreKPK (side, winner, loser, king1, king2, PieceList[winner][i]);
  389.  
  390.   else if (emtl[winner] == valueB + valueN)
  391.     s = ScoreKBNK (winner, king1, king2);
  392.  
  393.   else if (emtl[winner] > valueB)
  394.     s = 500 + emtl[winner] - DyingKing[king2] - 2 * distance (king1, king2);
  395.  
  396. #if defined(AMIGADB)&&defined(LATTICE)
  397.   {
  398.   if (abs((side == winner) ? s : -s) >= 10000)
  399.     flash(),fprintf(stderr, "eval3: (side == winner) ? s : -s = %d\n", (side == winner) ? s : -s);
  400.   return ((side == winner) ? s : -s);
  401.   }
  402. #else
  403.   return ((side == winner) ? s : -s);
  404. #endif
  405. }
  406.  
  407. short
  408. evaluate (register short int side,
  409.       register short int ply,
  410.       register short int alpha,
  411.       register short int beta,
  412.       short int INCscore,
  413.       short int *slk,    /* output single lone king */
  414.       short int *InChk)    /* output Check flag */
  415.  
  416. /*
  417.  * Compute an estimate of the score by adding the positional score from the
  418.  * previous ply to the material difference. If this score falls inside a
  419.  * window which is 180 points wider than the alpha-beta window (or within a
  420.  * 50 point window during quiescence search) call ScorePosition() to
  421.  * determine a score, otherwise return the estimated score. If one side has
  422.  * only a king and the other either has no pawns or no pieces then the
  423.  * function ScoreLoneKing() is called.
  424.  */
  425.  
  426. {
  427.   register short evflag, xside;
  428.   short s;
  429.  
  430.   xside = side ^ 1;
  431.   s = -Pscore[ply - 1] + mtl[side] - mtl[xside] - INCscore;
  432.   hung[white] = hung[black] = 0;
  433.   *slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) ||
  434.       (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0)));
  435.  
  436.   if (*slk)
  437.     evflag = false;
  438.   else
  439.     /* should we use the estimete or score the position */
  440.     evflag = (ply == 1 ||
  441.           ((ply <= Sdepth)) ||
  442.           ((ply == Sdepth + 1 || ply == (Sdepth + 2)) && (s > (alpha - xwndw) && s < (beta + xwndw))) ||
  443.        (ply > (Sdepth + 2) && s >= (alpha - EWNDW) && s <= (beta + EWNDW)));
  444. #ifdef DEBUG4
  445.   if (debuglevel & 1)
  446.     evflag = true;
  447. #endif
  448.   if (evflag)
  449.     {
  450.       /* score the position */
  451.       ataks (side, atak[side]);
  452.       if (Anyatak (side, PieceList[xside][0]))
  453.     return (10001 - ply);
  454.       ataks (xside, atak[xside]);
  455.       *InChk = Anyatak (xside, PieceList[side][0]);
  456.       EvalNodes++;
  457.       s = ScorePosition (side);
  458.     }
  459.   else
  460.     {
  461.       /* use the estimate but look at check and slk */
  462.       if (SqAtakd (PieceList[xside][0], side))
  463.     return (10001 - ply);
  464.       *InChk = SqAtakd (PieceList[side][0], xside);
  465.       if (*slk)
  466.     s = ScoreLoneKing (side);
  467.     }
  468.  
  469.   Pscore[ply] = s - mtl[side] + mtl[xside];
  470.   ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] : 0);
  471. #if defined(AMIGADB)&&defined(LATTICE)
  472.   {
  473.   if (abs(s) >= 10000)
  474.     flash(),fprintf(stderr, "eval4: s = %d\n", s);
  475.   return (s);
  476.   }
  477. #else
  478.   return (s);
  479. #endif
  480. }
  481.  
  482. inline
  483. void
  484. BRscan (short int sq, register short int *s, short int *mob)
  485.  
  486. /*
  487.  * Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the
  488.  * hung[] array if a pin is found.
  489.  */
  490. {
  491.   register short u, pin;
  492.   register unsigned char *ppos, *pdir;
  493.   short piece, *Kf;
  494.  
  495.   Kf = Kfield[c1];
  496.   *mob = 0;
  497.   piece = board[sq];
  498.   ppos = nextpos[piece][sq];
  499.   pdir = nextdir[piece][sq];
  500.   u = ppos[sq];
  501.   pin = -1;            /* start new direction */
  502.   do
  503.     {
  504.       *s += Kf[u];
  505.       if (color[u] == neutral)
  506.     {
  507.       (*mob)++;
  508.       if (ppos[u] == pdir[u])
  509.         pin = -1;        /* oops new direction */
  510.       u = ppos[u];
  511.     }
  512.       else if (pin < 0)
  513.     {
  514.       if (board[u] == pawn || board[u] == king)
  515.         u = pdir[u];
  516.       else
  517.         {
  518.           if (ppos[u] != pdir[u])
  519.         pin = u;    /* not on the edge and on to find a pin */
  520.           u = ppos[u];
  521.         }
  522.     }
  523.       else
  524.     {
  525.       if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  526.         {
  527.           if (color[pin] == c2)
  528.         {
  529.           *s += PINVAL;
  530.           if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1)
  531.             ++hung[c2];
  532.         }
  533.           else
  534.         *s += XRAY;
  535.         }
  536.       pin = -1;        /* new direction */
  537.       u = pdir[u];
  538.     }
  539.   } while (u != sq);
  540. }
  541.  
  542. inline
  543. short int
  544. KingScan (register short int sq)
  545.  
  546. /*
  547.  * Assign penalties if king can be threatened by checks, if squares near the
  548.  * king are controlled by the enemy (especially the queen), or if there are
  549.  * no pawns near the king. The following must be true: board[sq] == king c1
  550.  * == color[sq] c2 == otherside[c1]
  551.  */
  552.  
  553. #define ScoreThreat \
  554.     if (color[u] != c2)\
  555.       if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
  556.       else s -= 3
  557.  
  558. {
  559.   register short int s;
  560.   register short u;
  561.   register unsigned char *ppos, *pdir;
  562.   register short cnt, ok;
  563.  
  564.   s = 0;
  565.   cnt = 0;
  566.   if (HasBishop[c2] || HasQueen[c2])
  567.     {
  568.       ppos = nextpos[bishop][sq];
  569.       pdir = nextdir[bishop][sq];
  570.       u = ppos[sq];
  571.       do
  572.     {
  573.       if (atk2[u] & ctlBQ)
  574.         ScoreThreat;
  575.       u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  576.       } while (u != sq);
  577.     }
  578.   if (HasRook[c2] || HasQueen[c2])
  579.     {
  580.       ppos = nextpos[rook][sq];
  581.       pdir = nextdir[rook][sq];
  582.       u = ppos[sq];
  583.       do
  584.     {
  585.       if (atk2[u] & ctlRQ)
  586.         ScoreThreat;
  587.       u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  588.       } while (u != sq);
  589.     }
  590.   if (HasKnight[c2])
  591.     {
  592.       pdir = nextdir[knight][sq];
  593.       u = pdir[sq];
  594.       do
  595.     {
  596.       if (atk2[u] & ctlNN)
  597.         ScoreThreat;
  598.       u = pdir[u];
  599.       } while (u != sq);
  600.     }
  601.   s += (KSFTY * KTHRT[cnt]) / 16;
  602.  
  603.   cnt = 0;
  604.   ok = false;
  605.   pdir = nextpos[king][sq];
  606.   u = pdir[sq];
  607.   do
  608.     {
  609.       if (board[u] == pawn)
  610.     ok = true;
  611.       if (atk2[u] > atk1[u])
  612.     {
  613.       ++cnt;
  614.       if (atk2[u] & ctlQ)
  615.         if (atk2[u] > ctlQ + 1 && atk1[u] < ctlQ)
  616.           s -= 4 * KSFTY;
  617.     }
  618.       u = pdir[u];
  619.   } while (u != sq);
  620.   if (!ok)
  621.     s -= KSFTY;
  622.   if (cnt > 1)
  623.     s -= (KSFTY);
  624. #if defined(AMIGADB)&&defined(LATTICE)
  625.   {
  626.   if (abs(s) >= 10000)
  627.     flash(),fprintf(stderr, "eval5: s = %d\n", s);
  628.   return (s);
  629.   }
  630. #else
  631.   return (s);
  632. #endif
  633. }
  634.  
  635. inline
  636. int
  637. trapped (register short int sq)
  638.  
  639. /*
  640.  * See if the attacked piece has unattacked squares to move to. The following
  641.  * must be true: c1 == color[sq] c2 == otherside[c1]
  642.  */
  643.  
  644. {
  645.   register short u, piece;
  646.   register unsigned char *ppos, *pdir;
  647.  
  648.   piece = board[sq];
  649.   ppos = nextpos[ptype[c1][piece]][sq];
  650.   pdir = nextdir[ptype[c1][piece]][sq];
  651.   if (piece == pawn)
  652.     {
  653.       u = ppos[sq];        /* follow no captures thread */
  654.       if (color[u] == neutral)
  655.     {
  656.       if (atk1[u] >= atk2[u])
  657.         return (false);
  658.       if (atk2[u] < ctlP)
  659.         {
  660.           u = ppos[u];
  661.           if (color[u] == neutral && atk1[u] >= atk2[u])
  662.         return (false);
  663.         }
  664.     }
  665.       u = pdir[sq];        /* follow captures thread */
  666.       if (color[u] == c2)
  667.     return (false);
  668.       u = pdir[u];
  669.       if (color[u] == c2)
  670.     return (false);
  671.     }
  672.   else
  673.     {
  674.       u = ppos[sq];
  675.       do
  676.     {
  677.       if (color[u] != c1)
  678.         if (atk2[u] == 0 || board[u] >= piece)
  679.           return (false);
  680.       u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  681.       } while (u != sq);
  682.     }
  683.   return (true);
  684. }
  685.  
  686.  
  687. static inline short
  688. PawnValue(short int sq, short int side)
  689. /*
  690.  * Calculate the positional value for a pawn on 'sq'.
  691.  */
  692.  
  693. {
  694.     register short  j, fyle, rank;
  695.     register short  s, a1, a2, in_square, r, e;
  696.  
  697.     a1 = (atk1[sq] & 0x4FFF);
  698.     a2 = (atk2[sq] & 0x4FFF);
  699.     rank = row(sq);
  700.     fyle = column(sq);
  701.     s = 0;
  702.     if (c1 == white) {
  703.         s = Mwpawn[sq];
  704.         if ((sq == 11 && color[19] != neutral)
  705.             || (sq == 12 && color[20] != neutral))
  706.             s += PEDRNK2B;
  707.         if ((fyle == 0 || PC1[fyle - 1] == 0)
  708.             && (fyle == 7 || PC1[fyle + 1] == 0))
  709.             s += ISOLANI[fyle];
  710.         else if (PC1[fyle] > 1)
  711.             s += PDOUBLED;
  712.         if (a1 < ctlP && atk1[sq + 8] < ctlP) {
  713.             s += BACKWARD[a2 & 0xFF];
  714.             if (PC2[fyle] == 0)
  715.                 s += PWEAKH;
  716.             if (color[sq + 8] != neutral)
  717.                 s += PBLOK;
  718.         }
  719.         if (PC2[fyle] == 0) {
  720.             if (side == black)
  721.                 r = rank - 1;
  722.             else
  723.                 r = rank;
  724.             in_square = (row(bking) >= r && distance(sq, bking) < 8 - r);
  725.             if (a2 == 0 || side == white)
  726.                 e = 0;
  727.             else
  728.                 e = 1;
  729.             for (j = sq + 8; j < 64; j += 8)
  730.                 if (atk2[j] >= ctlP) {
  731.                     e = 2;
  732.                     break;
  733.                 } else if (atk2[j] > 0 || color[j] != neutral)
  734.                     e = 1;
  735.             if (e == 2)
  736.                 s += (stage * PassedPawn3[rank]) / 10;
  737.             else if (in_square || e == 1)
  738.                 s += (stage * PassedPawn2[rank]) / 10;
  739.             else if (emtl[black] > 0)
  740.                 s += (stage * PassedPawn1[rank]) / 10;
  741.             else
  742.                 s += PassedPawn0[rank];
  743.         }
  744.     } else if (c1 == black) {
  745.         s = Mbpawn[sq];
  746.         if ((sq == 51 && color[43] != neutral)
  747.             || (sq == 52 && color[44] != neutral))
  748.             s += PEDRNK2B;
  749.         if ((fyle == 0 || PC1[fyle - 1] == 0) &&
  750.             (fyle == 7 || PC1[fyle + 1] == 0))
  751.             s += ISOLANI[fyle];
  752.         else if (PC1[fyle] > 1)
  753.             s += PDOUBLED;
  754.         if (a1 < ctlP && atk1[sq - 8] < ctlP) {
  755.             s += BACKWARD[a2 & 0xFF];
  756.             if (PC2[fyle] == 0)
  757.                 s += PWEAKH;
  758.             if (color[sq - 8] != neutral)
  759.                 s += PBLOK;
  760.         }
  761.         if (PC2[fyle] == 0) {
  762.             if (side == white)
  763.                 r = rank + 1;
  764.             else
  765.                 r = rank;
  766.             in_square = (row(wking) <= r && distance(sq, wking) < r + 1);
  767.             if (a2 == 0 || side == black)
  768.                 e = 0;
  769.             else
  770.                 e = 1;
  771.             for (j = sq - 8; j >= 0; j -= 8)
  772.                 if (atk2[j] >= ctlP) {
  773.                     e = 2;
  774.                     break;
  775.                 } else if (atk2[j] > 0 || color[j] != neutral)
  776.                     e = 1;
  777.             if (e == 2)
  778.                 s += (stage * PassedPawn3[7 - rank]) / 10;
  779.             else if (in_square || e == 1)
  780.                 s += (stage * PassedPawn2[7 - rank]) / 10;
  781.             else if (emtl[white] > 0)
  782.                 s += (stage * PassedPawn1[7 - rank]) / 10;
  783.             else
  784.                 s += PassedPawn0[7 - rank];
  785.         }
  786.     }
  787.     if (a2 > 0) {
  788.         if (a1 == 0 || a2 > ctlP + 1) {
  789.             s += HUNGP;
  790.             ++hung[c1];
  791.             if (trapped(sq))
  792.                 ++hung[c1];
  793.         } else if (a2 > a1)
  794.             s += ATAKD;
  795.     }
  796. #if defined(AMIGADB)&&defined(LATTICE)
  797.   {
  798.   if (abs(s) >= 10000)
  799.     flash(),fprintf(stderr, "eval6: s = %d\n", s);
  800.   return (s);
  801.   }
  802. #else
  803.     return (s);
  804. #endif
  805. }
  806. inline
  807. short
  808. KnightValue (short int sq, short int side)
  809.  
  810. /*
  811.  * Calculate the positional value for a knight on 'sq'.
  812.  */
  813.  
  814. {
  815.   register short s, a2, a1;
  816.  
  817.   s = Mknight[c1][sq];
  818.   a2 = (atk2[sq] & 0x4FFF);
  819.   if (a2 > 0)
  820.     {
  821.       a1 = (atk1[sq] & 0x4FFF);
  822.       if (a1 == 0 || a2 > ctlBN + 1)
  823.     {
  824.       s += HUNGP;
  825.       ++hung[c1];
  826.       if (trapped (sq))
  827.         ++hung[c1];
  828.     }
  829.       else if (a2 >= ctlBN || a1 < ctlP)
  830.     s += ATAKD;
  831.     }
  832. #if defined(AMIGADB)&&defined(LATTICE)
  833.   {
  834.   if (abs(s) >= 10000)
  835.     flash(),fprintf(stderr, "eval7: s = %d\n", s);
  836.   return (s);
  837.   }
  838. #else
  839.   return (s);
  840. #endif
  841. }
  842.  
  843. inline
  844. short
  845. BishopValue (short int sq, short int side)
  846.  
  847. /*
  848.  * Calculate the positional value for a bishop on 'sq'.
  849.  */
  850.  
  851. {
  852.   register short a2, a1;
  853.   short s, mob;
  854.  
  855.   s = Mbishop[c1][sq];
  856.   BRscan (sq, &s, &mob);
  857.   s += BMBLTY[mob];
  858.   a2 = (atk2[sq] & 0x4FFF);
  859.   if (a2 > 0)
  860.     {
  861.       a1 = (atk1[sq] & 0x4FFF);
  862.       if (a1 == 0 || a2 > ctlBN + 1)
  863.     {
  864.       s += HUNGP;
  865.       ++hung[c1];
  866.       if (trapped (sq))
  867.         ++hung[c1];
  868.     }
  869.       else if (a2 >= ctlBN || a1 < ctlP)
  870.     s += ATAKD;
  871.     }
  872. #if defined(AMIGADB)&&defined(LATTICE)
  873.   {
  874.   if (abs(s) >= 10000)
  875.     flash(),fprintf(stderr, "eval8: s = %d\n", s);
  876.   return (s);
  877.   }
  878. #else
  879.   return (s);
  880. #endif
  881. }
  882.  
  883. inline
  884. short
  885. RookValue (register short int sq, short int side)
  886.  
  887. /*
  888.  * Calculate the positional value for a rook on 'sq'.
  889.  */
  890.  
  891. {
  892.   register short fyle, a2, a1;
  893.   short s, mob;
  894.  
  895.   s = RookBonus;
  896.   BRscan (sq, &s, &mob);
  897.   s += RMBLTY[mob];
  898.   fyle = column (sq);
  899.   if (PC1[fyle] == 0)
  900.     s += RHOPN;
  901.   if (PC2[fyle] == 0)
  902.     s += RHOPNX;
  903.   if (pmtl[c2] > 100 && row (sq) == rank7[c1])
  904.     s += 10;
  905.   if (stage > 2)
  906.     s += 14 - taxicab (sq, EnemyKing);
  907.   a2 = (atk2[sq] & 0x4FFF);
  908.   if (a2 > 0)
  909.     {
  910.       a1 = (atk1[sq] & 0x4FFF);
  911.       if (a1 == 0 || a2 > ctlR + 1)
  912.     {
  913.       s += HUNGP;
  914.       ++hung[c1];
  915.  
  916.       if (trapped (sq))
  917.         ++hung[c1];
  918.     }
  919.       else if (a2 >= ctlR || a1 < ctlP)
  920.     s += ATAKD;
  921.     }
  922. #if defined(AMIGADB)&&defined(LATTICE)
  923.   {
  924.   if (abs(s) >= 10000)
  925.     flash(),fprintf(stderr, "eval9: s = %d\n", s);
  926.   return (s);
  927.   }
  928. #else
  929.   return (s);
  930. #endif
  931. }
  932.  
  933. inline
  934. short
  935. QueenValue (register short int sq, short int side)
  936.  
  937. /*
  938.  * Calculate the positional value for a queen on 'sq'.
  939.  */
  940.  
  941. {
  942.   register short s, a2, a1;
  943.  
  944.   s = ((distance (sq, EnemyKing) < 3) ? 12 : 0);
  945.   if (stage > 2)
  946.     s += 14 - taxicab (sq, EnemyKing);
  947.   a2 = (atk2[sq] & 0x4FFF);
  948.   if (a2 > 0)
  949.     {
  950.       a1 = (atk1[sq] & 0x4FFF);
  951.       if (a1 == 0 || a2 > ctlQ + 1)
  952.     {
  953.       s += HUNGP;
  954.       ++hung[c1];
  955.       if (trapped (sq))
  956.         ++hung[c1];
  957.     }
  958.       else if (a2 >= ctlQ || a1 < ctlP)
  959.     s += ATAKD;
  960.     }
  961. #if defined(AMIGADB)&&defined(LATTICE)
  962.   {
  963.   if (abs(s) >= 10000)
  964.     flash(),fprintf(stderr, "eval10: s = %d\n", s);
  965.   return (s);
  966.   }
  967. #else
  968.   return (s);
  969. #endif
  970. }
  971.  
  972. inline
  973. short
  974. KingValue (short int sq, short int side)
  975.  
  976. /*
  977.  * Calculate the positional value for a king on 'sq'.
  978.  */
  979.  
  980. {
  981.   register short fyle, a2, a1;
  982.   short s;
  983.   s = (emtl[side ^ 1] > KINGPOSLIMIT) ? Mking[c1][sq] : Mking[c1][sq] / 2;
  984.   if (KSFTY > 0)
  985.     if (Developed[c2] || stage > 0)
  986.       s += KingScan (sq);
  987.   if (castld[c1])
  988.     s += KCASTLD;
  989.   else if (Mvboard[kingP[c1]])
  990.     s += KMOVD;
  991.  
  992.   fyle = column (sq);
  993.   if (PC1[fyle] == 0)
  994.     s += KHOPN;
  995.   if (PC2[fyle] == 0)
  996.     s += KHOPNX;
  997.   switch (fyle)
  998.     {
  999.     case 5:
  1000.       if (PC1[7] == 0)
  1001.     s += KHOPN;
  1002.       if (PC2[7] == 0)
  1003.     s += KHOPNX;
  1004.       /* Fall through */
  1005.     case 4:
  1006.     case 6:
  1007.     case 0:
  1008.       if (PC1[fyle + 1] == 0)
  1009.     s += KHOPN;
  1010.       if (PC2[fyle + 1] == 0)
  1011.     s += KHOPNX;
  1012.       break;
  1013.     case 2:
  1014.       if (PC1[0] == 0)
  1015.     s += KHOPN;
  1016.       if (PC2[0] == 0)
  1017.     s += KHOPNX;
  1018.       /* Fall through */
  1019.     case 3:
  1020.     case 1:
  1021.     case 7:
  1022.       if (PC1[fyle - 1] == 0)
  1023.     s += KHOPN;
  1024.       if (PC2[fyle - 1] == 0)
  1025.     s += KHOPNX;
  1026.       break;
  1027.     default:
  1028.       /* Impossible! */
  1029.       break;
  1030.     }
  1031.  
  1032.   a2 = (atk2[sq] & 0x4FFF);
  1033.   if (a2 > 0)
  1034.     {
  1035.       a1 = (atk1[sq] & 0x4FFF);
  1036.       if (a1 == 0 || a2 > ctlK + 1)
  1037.     {
  1038.       s += HUNGP;
  1039.       ++hung[c1];
  1040.     }
  1041.       else
  1042.     s += ATAKD;
  1043.     }
  1044. #if defined(AMIGADB)&&defined(LATTICE)
  1045.   {
  1046.   if (abs(s) >= 10000)
  1047.     flash(),fprintf(stderr, "eval11: s = %d\n", s);
  1048.   return (s);
  1049.   }
  1050. #else
  1051.   return (s);
  1052. #endif
  1053. }
  1054.  
  1055. #if !defined NOSCORESPACE
  1056. inline
  1057. void
  1058. ScoreSpace (void)
  1059. {
  1060.   register short *b, *w, *sw, *sb;
  1061.   register short sBl, sWh;
  1062.   sBl = sWh = 0;
  1063.   for (b = &atak[black][63], w = &atak[white][63], sw = &SpaceBonusW[63], sb = &SpaceBonusB[63];
  1064.        sw > &SpaceBonusW[0];
  1065.        b--, w--, sw--, sb--)
  1066.     {
  1067.       if (*b > *w)
  1068.     {
  1069.       if (*b > ctlR)
  1070.         sBl += *sb;
  1071.     }
  1072.       else if (*b < *w)
  1073.     if (*w > ctlR)
  1074.       sWh += *sw;
  1075.     }
  1076.   pscore[white] += (sWh);
  1077.   pscore[black] += (sBl);
  1078.   sscore[white] = sWh;
  1079.   sscore[black] = sBl;
  1080. }
  1081.  
  1082. #endif
  1083.  
  1084.  
  1085.  
  1086. short int
  1087. ScorePosition (register short int side)
  1088.  
  1089. /*
  1090.  * Perform normal static evaluation of board position. A score is generated
  1091.  * for each piece and these are summed to get a score for each side.
  1092.  */
  1093.  
  1094. {
  1095.   register short int score;
  1096.   register short sq, s, i, xside;
  1097.  
  1098.   UpdateWeights ();
  1099.   xside = side ^ 1;
  1100.   hung[white]= hung[black] = pscore[white] = pscore[black] = 0;
  1101. #if !defined NOSCORESPACE
  1102.   if (stage < SCORESPLIM)
  1103.     ScoreSpace ();
  1104. #endif
  1105.   for (c1 = white; c1 <= black; c1++)
  1106.     {
  1107.       c2 = c1 ^ 1;
  1108.       /* atk1 is array of atacks on squares by my side */
  1109.       atk1 = atak[c1];
  1110.       /* atk2 is array of atacks on squares by other side */
  1111.       atk2 = atak[c2];
  1112.       /* same for PC1 and PC2 */
  1113.       PC1 = PawnCnt[c1];
  1114.       PC2 = PawnCnt[c2];
  1115.       for (i = PieceCnt[c1]; i >= 0; i--)
  1116.     {
  1117.       sq = PieceList[c1][i];
  1118.       switch (board[sq])
  1119.         {
  1120.         case pawn:
  1121.           s = PawnValue (sq, side);
  1122.           break;
  1123.         case knight:
  1124.           s = KnightValue (sq, side);
  1125.           break;
  1126.         case bishop:
  1127.           s = BishopValue (sq, side);
  1128.           break;
  1129.         case rook:
  1130.           s = RookValue (sq, side);
  1131.           break;
  1132.         case queen:
  1133.           s = QueenValue (sq, side);
  1134.           break;
  1135.         case king:
  1136.           s = KingValue (sq, side);
  1137.           break;
  1138.         default:
  1139.           s = 0;
  1140.           break;
  1141.         }
  1142.       pscore[c1] += s;
  1143.       svalue[sq] = s;
  1144.     }
  1145.     }
  1146.   if (hung[side] > 1)
  1147.     pscore[side] += HUNGX;
  1148.   if (hung[xside] > 1)
  1149.     pscore[xside] += HUNGX;
  1150.  
  1151.   score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  1152.   if (dither)
  1153.     {
  1154.       if (flag.hash)
  1155.     srand (starttime + (unsigned int) hashbd);
  1156.       score += urand () % dither;
  1157.     }
  1158.  
  1159.   if (score > 0 && pmtl[side] == 0)
  1160.     if (emtl[side] < valueR)
  1161.       score = 0;
  1162.     else if (score < valueR)
  1163.       score /= 2;
  1164.   if (score < 0 && pmtl[xside] == 0)
  1165.     if (emtl[xside] < valueR)
  1166.       score = 0;
  1167.     else if (-score < valueR)
  1168.       score /= 2;
  1169.  
  1170.   if (mtl[xside] == valueK && emtl[side] > valueB)
  1171.     score += 200;
  1172.   if (mtl[side] == valueK && emtl[xside] > valueB)
  1173.     score -= 200;
  1174. #if defined(AMIGADB)&&defined(LATTICE)
  1175.   {
  1176.   if (abs(score) >= 10000)
  1177.     flash(),fprintf(stderr, "eval12: score = %d\n", score);
  1178.   return (score);
  1179.   }
  1180. #else
  1181.   return (score);
  1182. #endif
  1183. }
  1184. static inline void
  1185. BlendBoard (const short int a[64], const short int b[64], short int c[64])
  1186. {
  1187.   register int sq, s;
  1188.   s = 10 - stage;
  1189.   for (sq = 0; sq < 64; sq++)
  1190.     c[sq] = ((a[sq] * s) + (b[sq] * stage)) / 10;
  1191. }
  1192.  
  1193.  
  1194. static inline void
  1195. CopyBoard (const short int a[64], short int b[64])
  1196. {
  1197.   register short *sqa, *sqb;
  1198.   for (sqa = a, sqb = b; sqa < a + 64;)
  1199.     *sqb++ = *sqa++;
  1200. }
  1201.  
  1202.  
  1203. void
  1204. ExaminePosition (void)
  1205.  
  1206. /*
  1207.  * This is done one time before the search is started. Set up arrays Mwpawn,
  1208.  * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
  1209.  * to determine the positional value of each piece.
  1210.  */
  1211.  
  1212. {
  1213.   register short i, sq;
  1214.   short wpadv, bpadv, wstrong, bstrong, z, side, pp, j, k, val, Pd, fyle,
  1215.    rank;
  1216.   static short PawnStorm = false;
  1217.  
  1218.   ataks (white, atak[white]);
  1219.   ataks (black, atak[black]);
  1220.   UpdateWeights ();
  1221.   HasKnight[white] = HasKnight[black] = 0;
  1222.   HasBishop[white] = HasBishop[black] = 0;
  1223.   HasRook[white] = HasRook[black] = 0;
  1224.   HasQueen[white] = HasQueen[black] = 0;
  1225.   for (side = white; side <= black; side++)
  1226.     for (i = PieceCnt[side]; i >= 0; i--)
  1227.       switch (board[PieceList[side][i]])
  1228.     {
  1229.     case knight:
  1230.       ++HasKnight[side];
  1231.       break;
  1232.     case bishop:
  1233.       ++HasBishop[side];
  1234.       break;
  1235.     case rook:
  1236.       ++HasRook[side];
  1237.       break;
  1238.     case queen:
  1239.       ++HasQueen[side];
  1240.       break;
  1241.     }
  1242.   if (!Developed[white])
  1243.     Developed[white] = (board[1] != knight && board[2] != bishop &&
  1244.             board[5] != bishop && board[6] != knight);
  1245.   if (!Developed[black])
  1246.     Developed[black] = (board[57] != knight && board[58] != bishop &&
  1247.             board[61] != bishop && board[62] != knight);
  1248.   if (!PawnStorm && stage < 5)
  1249.     PawnStorm = ((column (wking) < 3 && column (bking) > 4) ||
  1250.          (column (wking) > 4 && column (bking) < 3));
  1251.  
  1252.   CopyBoard (pknight, Mknight[white]);
  1253.   CopyBoard (pknight, Mknight[black]);
  1254.   CopyBoard (pbishop, Mbishop[white]);
  1255.   CopyBoard (pbishop, Mbishop[black]);
  1256.   BlendBoard (KingOpening, KingEnding, Mking[white]);
  1257.   BlendBoard (KingOpening, KingEnding, Mking[black]);
  1258.  
  1259.   for (sq = 0; sq < 64; sq++)
  1260.     {
  1261.       fyle = column (sq);
  1262.       rank = row (sq);
  1263.       wstrong = bstrong = true;
  1264.       for (i = sq; i < 64; i += 8)
  1265.     if (Patak (black, i))
  1266.       {
  1267.         wstrong = false;
  1268.         break;
  1269.       }
  1270.       for (i = sq; i >= 0; i -= 8)
  1271.     if (Patak (white, i))
  1272.       {
  1273.         bstrong = false;
  1274.         break;
  1275.       }
  1276.       wpadv = bpadv = PADVNCM;
  1277.       if ((fyle == 0 || PawnCnt[white][fyle - 1] == 0) && (fyle == 7 || PawnCnt[white][fyle + 1] == 0))
  1278.     wpadv = PADVNCI;
  1279.       if ((fyle == 0 || PawnCnt[black][fyle - 1] == 0) && (fyle == 7 || PawnCnt[black][fyle + 1] == 0))
  1280.     bpadv = PADVNCI;
  1281.       Mwpawn[sq] = (wpadv * PawnAdvance[sq]) / 10;
  1282.       Mbpawn[sq] = (bpadv * PawnAdvance[63 - sq]) / 10;
  1283.       Mwpawn[sq] += PawnBonus;
  1284.       Mbpawn[sq] += PawnBonus;
  1285.       if (Mvboard[kingP[white]])
  1286.     {
  1287.       if ((fyle < 3 || fyle > 4) && distance (sq, wking) < 3)
  1288.         Mwpawn[sq] += PAWNSHIELD;
  1289.     }
  1290.       else if (rank < 3 && (fyle < 2 || fyle > 5))
  1291.     Mwpawn[sq] += PAWNSHIELD / 2;
  1292.       if (Mvboard[kingP[black]])
  1293.     {
  1294.       if ((fyle < 3 || fyle > 4) && distance (sq, bking) < 3)
  1295.         Mbpawn[sq] += PAWNSHIELD;
  1296.     }
  1297.       else if (rank > 4 && (fyle < 2 || fyle > 5))
  1298.     Mbpawn[sq] += PAWNSHIELD / 2;
  1299.       if (PawnStorm)
  1300.     {
  1301.       if ((column (wking) < 4 && fyle > 4) || (column (wking) > 3 && fyle < 3))
  1302.         Mwpawn[sq] += 3 * rank - 21;
  1303.       if ((column (bking) < 4 && fyle > 4) || (column (bking) > 3 && fyle < 3))
  1304.         Mbpawn[sq] -= 3 * rank;
  1305.     }
  1306.       Mknight[white][sq] += 5 - distance (sq, bking);
  1307.       Mknight[white][sq] += 5 - distance (sq, wking);
  1308.       Mknight[black][sq] += 5 - distance (sq, wking);
  1309.       Mknight[black][sq] += 5 - distance (sq, bking);
  1310.       Mbishop[white][sq] += BishopBonus;
  1311.       Mbishop[black][sq] += BishopBonus;
  1312.       for (i = PieceCnt[black]; i >= 0; i--)
  1313.     if (distance (sq, PieceList[black][i]) < 3)
  1314.       Mknight[white][sq] += KNIGHTPOST;
  1315.       for (i = PieceCnt[white]; i >= 0; i--)
  1316.     if (distance (sq, PieceList[white][i]) < 3)
  1317.       Mknight[black][sq] += KNIGHTPOST;
  1318.       if (wstrong)
  1319.     Mknight[white][sq] += KNIGHTSTRONG;
  1320.       if (bstrong)
  1321.     Mknight[black][sq] += KNIGHTSTRONG;
  1322.       if (wstrong)
  1323.     Mbishop[white][sq] += BISHOPSTRONG;
  1324.       if (bstrong)
  1325.     Mbishop[black][sq] += BISHOPSTRONG;
  1326.  
  1327.       if (HasBishop[white] == 2)
  1328.     Mbishop[white][sq] += 8;
  1329.       if (HasBishop[black] == 2)
  1330.     Mbishop[black][sq] += 8;
  1331.       if (HasKnight[white] == 2)
  1332.     Mknight[white][sq] += 5;
  1333.       if (HasKnight[black] == 2)
  1334.     Mknight[black][sq] += 5;
  1335.  
  1336.       Kfield[white][sq] = Kfield[black][sq] = 0;
  1337.       if (distance (sq, wking) == 1)
  1338.     Kfield[black][sq] = KATAK;
  1339.       if (distance (sq, bking) == 1)
  1340.     Kfield[white][sq] = KATAK;
  1341.       Pd = 0;
  1342.       for (k = 0; k <= PieceCnt[white]; k++)
  1343.     {
  1344.       i = PieceList[white][k];
  1345.       if (board[i] == pawn)
  1346.         {
  1347.           pp = true;
  1348.           z = i + ((row (i) == 6) ? 8 : 16);
  1349.           for (j = i + 8; j < 64; j += 8)
  1350.         if (Patak (black, j) || board[j] == pawn)
  1351.           {
  1352.             pp = false;
  1353.             break;
  1354.           }
  1355.           Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  1356.         }
  1357.     }
  1358.       for (k = 0; k <= PieceCnt[black]; k++)
  1359.     {
  1360.       i = PieceList[black][k];
  1361.       if (board[i] == pawn)
  1362.         {
  1363.           pp = true;
  1364.           z = i - ((row (i) == 1) ? 8 : 16);
  1365.           for (j = i - 8; j >= 0; j -= 8)
  1366.         if (Patak (white, j) || board[j] == pawn)
  1367.           {
  1368.             pp = false;
  1369.             break;
  1370.           }
  1371.           Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  1372.         }
  1373.     }
  1374.       if (Pd != 0)
  1375.     {
  1376.       val = (Pd * stage2) / 10;
  1377.       Mking[white][sq] -= val;
  1378.       Mking[black][sq] -= val;
  1379.     }
  1380.     }
  1381. }
  1382.  
  1383. void
  1384. UpdateWeights (void)
  1385.  
  1386. /*
  1387.  * If material balance has changed, determine the values for the positional
  1388.  * evaluation terms.
  1389.  */
  1390.  
  1391. {
  1392.   register short s1;
  1393.  
  1394.   emtl[white] = mtl[white] - pmtl[white] - valueK;
  1395.   emtl[black] = mtl[black] - pmtl[black] - valueK;
  1396.   tmtl = emtl[white] + emtl[black];
  1397.   s1 = ((tmtl > 6600) ? 0 : ((tmtl < 1400) ? 10 : (6600 - tmtl) / 520));
  1398.   if (s1 != stage)
  1399.     {
  1400.       stage = s1;
  1401.       stage2 = ((tmtl > 3600) ? 0 : ((tmtl < 1400) ? 10 : (3600 - tmtl) / 220));
  1402.       PEDRNK2B = -15;        /* centre pawn on 2nd rank & blocked */
  1403.       PBLOK = -4;        /* blocked backward pawn */
  1404.       PDOUBLED = -14;        /* doubled pawn */
  1405.       PWEAKH = -4;        /* weak pawn on half open file */
  1406.       PAWNSHIELD = 10 - stage;    /* pawn near friendly king */
  1407.       PADVNCM = 10;        /* advanced pawn multiplier */
  1408.       PADVNCI = 7;        /* muliplier for isolated pawn */
  1409.       PawnBonus = stage;
  1410.  
  1411.       KNIGHTPOST = (stage + 2) / 3;    /* knight near enemy pieces */
  1412.       KNIGHTSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  1413.  
  1414.       BISHOPSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  1415.       BishopBonus = BBONUS * stage;
  1416.  
  1417.       RHOPN = 10;        /* rook on half open file */
  1418.       RHOPNX = 4;
  1419.       RookBonus = RBONUS * stage;
  1420.  
  1421.       XRAY = 8;            /* Xray attack on piece */
  1422.       PINVAL = 10;        /* Pin */
  1423.  
  1424.       KHOPN = (3 * stage - 30) / 2;    /* king on half open file */
  1425.       KHOPNX = KHOPN / 2;
  1426.       KCASTLD = 10 - stage;
  1427.       KMOVD = -40 / (stage + 1);/* king moved before castling */
  1428.       KATAK = (10 - stage) / 2;    /* B,R attacks near enemy king */
  1429.       KSFTY = ((stage < 8) ? KINGSAFETY - 2 * stage : 0);
  1430.  
  1431.       ATAKD = -6;        /* defender > attacker */
  1432.       HUNGP = -12;        /* each hung piece */
  1433.       HUNGX = -18;        /* extra for >1 hung piece */
  1434.     }
  1435. }
  1436.